home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-gmenu / GMenuSimpleEditor / menufilewriter.py < prev    next >
Encoding:
Python Source  |  2009-03-17  |  6.4 KB  |  193 lines

  1. #
  2. # Copyright (C) 2005 Red Hat, Inc.
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. #
  18.  
  19. import os
  20. import errno
  21. import pwd
  22. import gobject
  23. import menutreemodel
  24.  
  25. DTD_DECLARATION = '<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"\n' \
  26.                   ' "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">\n\n'
  27.  
  28. class MenuFileWriterError (Exception):
  29.     pass
  30.  
  31. def get_home_dir ():
  32.     try:
  33.         pw = pwd.getpwuid (os.getuid ())
  34.         if pw.pw_dir:
  35.             return pw.pw_dir
  36.     except KeyError:
  37.         pass
  38.  
  39.     if os.environ.has_key ("HOME"):
  40.         return os.environ["HOME"]
  41.     else:
  42.         raise MenuFileWriterError (_("Cannot find home directory: not set in /etc/passwd and no value for $HOME in environment"))
  43.  
  44. def get_user_menu_file_path (menu_file):
  45.     config_dir = None
  46.     if os.environ.has_key ("XDG_CONFIG_HOME"):
  47.         config_dir = os.environ["XDG_CONFIG_HOME"]
  48.     if not config_dir:
  49.         config_dir = os.path.join (get_home_dir (), ".config")
  50.     
  51.     return os.path.join (config_dir, "menus", menu_file)
  52.  
  53. def write_file (filename, contents):
  54.     dir = os.path.dirname (filename)
  55.     try:
  56.         os.makedirs (dir)
  57.     except os.error, (err, str):
  58.         if err != errno.EEXIST:
  59.             raise
  60.     
  61.     temp = filename + ".new"
  62.     try:
  63.         f = file (temp, "w")
  64.     except:
  65.         temp = None
  66.         f = file (filename, "w")
  67.     
  68.     try:
  69.         f.write (contents)
  70.         f.close ()
  71.     except:
  72.         if temp != None:
  73.             os.remove (temp)
  74.         raise
  75.  
  76.     if temp != None:
  77.         os.rename (temp, filename)
  78.  
  79. class MenuFileWriter:
  80.     def __init__ (self, menu_tree_model):
  81.         self.model = menu_tree_model
  82.  
  83.         self.sync_idle_handlers = {}
  84.  
  85.     def __del__ (self):
  86.         for (id, iter) in self.sync_idle_handlers:
  87.             gobject.source_remove (id)
  88.  
  89.     def __append_menu (self, contents, indent, iter, system_menu_file = None):
  90.         has_changes = False
  91.         orig_contents = contents
  92.         
  93.         contents += indent + "<Menu>\n"
  94.         contents += indent + "  <Name>%s</Name>\n" % self.model[iter][self.model.COLUMN_ID]
  95.  
  96.         if system_menu_file:
  97.             contents += indent + '  <MergeFile type="parent">%s</MergeFile>\n' % system_menu_file
  98.  
  99.         includes = []
  100.         excludes = []
  101.  
  102.         child_iter = self.model.iter_children (iter)
  103.         while child_iter:
  104.             if self.model[child_iter][self.model.COLUMN_IS_ENTRY]:
  105.                 desktop_file_id = self.model[child_iter][self.model.COLUMN_ID]
  106.                 system_visible  = self.model[child_iter][self.model.COLUMN_SYSTEM_VISIBLE]
  107.                 user_visible    = self.model[child_iter][self.model.COLUMN_USER_VISIBLE]
  108.  
  109.                 if not system_visible and user_visible:
  110.                     includes.append (desktop_file_id)
  111.                 elif system_visible and not user_visible:
  112.                     excludes.append (desktop_file_id)
  113.  
  114.             child_iter = self.model.iter_next (child_iter)
  115.  
  116.         if len (includes) > 0:
  117.             contents += indent + "  <Include>\n"
  118.             for desktop_file_id in includes:
  119.                 contents += indent + "    <Filename>%s</Filename>\n" % desktop_file_id
  120.             contents += indent + "  </Include>\n"
  121.             has_changes = True
  122.         
  123.         if len (excludes) > 0:
  124.             contents += indent + "  <Exclude>\n"
  125.             for desktop_file_id in excludes:
  126.                 contents += indent + "    <Filename>%s</Filename>\n" % desktop_file_id
  127.             contents += indent + "  </Exclude>\n"
  128.             has_changes = True
  129.         
  130.         child_iter = self.model.iter_children (iter)
  131.         while child_iter:
  132.             if not self.model[child_iter][self.model.COLUMN_IS_ENTRY]:
  133.                 (contents, subdir_has_changes) = self.__append_menu (contents,
  134.                                                                      indent + "  ",
  135.                                                                      child_iter)
  136.                 if not has_changes:
  137.                     has_changes = subdir_has_changes
  138.  
  139.             child_iter = self.model.iter_next (child_iter)
  140.  
  141.         if has_changes:
  142.             return (contents + indent + "</Menu>\n", True)
  143.         else:
  144.             return (orig_contents, False)
  145.  
  146.     def sync (self, iter):
  147.         menu_file = self.model[iter][self.model.COLUMN_MENU_FILE]
  148.         system_menu_file = menutreemodel.lookup_system_menu_file (menu_file)
  149.         
  150.         (contents, has_changes) = self.__append_menu (DTD_DECLARATION,
  151.                                                       "",
  152.                                                       iter,
  153.                                                       system_menu_file)
  154.  
  155.         if not has_changes:
  156.             try:
  157.                 os.remove (get_user_menu_file_path (menu_file))
  158.             except:
  159.                 pass
  160.             return
  161.             
  162.         write_file (get_user_menu_file_path (menu_file), contents)
  163.  
  164.     def __sync_idle_handler_func (self, iter):
  165.         self.sync (iter)
  166.         del self.sync_idle_handlers[iter]
  167.         return False
  168.  
  169.     def queue_sync (self, iter):
  170.         def find_menu_file_parent (model, iter):
  171.             if model[iter][model.COLUMN_MENU_FILE]:
  172.                 return iter
  173.             
  174.             parent_iter = model.iter_parent (iter)
  175.             if not parent_iter:
  176.                 return None
  177.  
  178.             return find_menu_file_parent (model, parent_iter)
  179.  
  180.         menu_file_iter = find_menu_file_parent (self.model, iter)
  181.         if not menu_file_iter:
  182.             return
  183.  
  184.         menu_file_path = self.model.get_string_from_iter (menu_file_iter)
  185.         for iter in self.sync_idle_handlers:
  186.             path = self.model.get_string_from_iter (iter)
  187.             if path == menu_file_path:
  188.                 return
  189.  
  190.         id = gobject.idle_add (self.__sync_idle_handler_func, menu_file_iter)
  191.  
  192.         self.sync_idle_handlers[menu_file_iter] = id
  193.